package com.crm.system.service.impl.cluePoolManager;

import com.alibaba.fastjson.JSONObject;
import com.crm.common.model.DhPageInfo;
import com.crm.common.model.Enum.*;
import com.crm.common.util.CommonUtils;
import com.crm.common.util.DateUtil;
import com.crm.common.util.HttpHelper;
import com.crm.common.util.RedisUtil;
import com.crm.dao.mapper.customerManager.QccSearchMapper;
import com.crm.model.entity.cluePoolManager.*;
import com.crm.model.entity.common.Dictionary;
import com.crm.model.entity.customerManager.QccSearch;
import com.crm.model.entity.sys.UserAccount;
import com.crm.model.entity.sys.permissionManagement.SysCompany;
import com.crm.model.qo.cluePoolManager.ClueAddQO;
import com.crm.model.qo.cluePoolManager.ClueExtentQO;
import com.crm.model.qo.cluePoolManager.ClueQO;
import com.crm.model.qo.cluePoolManager.ClueSeniorQO;
import com.crm.model.vo.cluePoolManager.ClueEditVO;
import com.crm.model.vo.cluePoolManager.ClueVO;
import com.crm.model.vo.cluePoolManager.UserCompanyVO;
import com.crm.model.vo.customerManager.QccSearchWideVO;
import com.crm.redis.service.cluePoolManager.ClueRedisService;
import com.crm.service.cluePoolManager.*;
import com.crm.service.common.DictionaryDbService;
import com.crm.service.sys.permissionManagement.SysCompanyDbService;
import com.crm.system.service.cluePoolManager.ClueReturnService;
import com.crm.system.service.cluePoolManager.ClueService;
import com.crm.system.service.common.DictionaryService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpHead;
import org.apache.shiro.SecurityUtils;
import org.json.JSONException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.regex.Pattern;

import static java.lang.System.out;

/**
 * @Author yincuimei
 * @Date 2021/1/6 16:56
 */
@Service
public class ClueServiceImpl implements ClueService {

    @Autowired
    private ClueDbService clueDbService;
    @Autowired
    private CluePoolPublicDbService cluePoolPublicDbService;
    @Autowired
    private CluePoolPrivateDbService cluePoolPrivateDbService;
    @Autowired
    private ClueReceiveDbService clueReceiveDbService;
    @Autowired
    private ClueReturnService clueReturnService;
    @Autowired
    private CluePoolRuleDbService cluePoolRuleDbService;
    @Autowired
    private ClueReturnDbService clueReturnDbService;
    @Autowired
    private DictionaryDbService dictionaryDbService;
    @Autowired
    private ClueRedisService clueRedisService;
    @Autowired
    private DictionaryService dictionaryService;
    @Autowired
    private SysCompanyDbService sysCompanyDbService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private QccSearchMapper qccSearchMapper;


    /**
     * 线索公海--查看线索清单(私有池、分公司公有池、全国公有池的线索)
     * @param clueQO        ---普通搜索条件
     * @param clueSeniorQO  ---高级搜索条件(包括行业、成立年限、注册资本、企业类型、参保人数、有无联系电话、有无联系人、有无联系邮箱)
     * @param pageIndex     ---页码
     * @param pageSize      ---分页大小
     * @param sortName      ---排序字段名
     * @param sortOrder     ---排序规则(ASC/DESC)
     * @return
     */
    @Override
    public DhPageInfo<ClueVO> selectPublicPoolClueList(ClueQO clueQO,ClueSeniorQO clueSeniorQO,Integer pageIndex, Integer pageSize, String sortName, String sortOrder) {
        if (pageIndex != null && pageSize != null) {
            PageHelper.startPage(pageIndex, pageSize);
        }

        //增加删除状态查询条件(0:正常;1:已删除)
        clueQO.setDeleteStatus((short) StatusCodeEnum.NORMAL_CODE.getState());

        //排序
        StringBuilder order = new StringBuilder();
        if(!StringUtils.isBlank(sortName)&&!StringUtils.isBlank(sortOrder)){
            switch(sortName){
                case "inPoolTime":
                {
                    order.append("inPoolTime ").append(sortOrder);//在池时间
                }
                break;
                case "source":
                {
                    order.append("source ").append(sortOrder);//线索来源
                }
                break;
                case "clueState":
                {
                    order.append("clue_state ").append(sortOrder);//线索状态
                }
                break;
                default:
                    break;
            }
        }
        List<ClueVO> clueVOList = clueDbService.selectPublicPoolClueList(clueQO,clueSeniorQO,order.toString());
        if(clueVOList != null && clueVOList.size() > 0){
            for(ClueVO clueVO : clueVOList){
                long collectionTimes = clueReceiveDbService.selectReceiveCountByClueId(clueVO.getClueId());//领取次数
                clueVO.setCollectionTimes(collectionTimes);
                long returnTimes = clueReturnDbService.selectReturnCountByClueId(clueVO.getClueId());//退回次数
                clueVO.setReturnTimes(returnTimes);
                if(!StringUtils.isBlank(clueVO.getSource())){
                    Dictionary dictionary = dictionaryService.selectDictionaryByOne(DictionaryEnum.CLUE_SOURCE.getTypeCode(),clueVO.getSource());
                    if(dictionary!=null){
                        clueVO.setSource(dictionary.getDictName());
                    }
                }
            }
        }
        PageInfo<ClueVO> pageInfo = new PageInfo<ClueVO>(clueVOList);
        return new DhPageInfo<ClueVO>(pageInfo, clueVOList);
    }

    /**
     * 线索公海--查看线索清单(个人池的线索)
     * @param clueQO        ---普通搜索条件
     * @param clueSeniorQO  ---高级搜索条件(包括行业、成立年限、注册资本、企业类型、参保人数、有无联系电话、有无联系人、有无联系邮箱)
     * @param pageIndex     ---页码
     * @param pageSize      ---分页大小
     * @param sortName      ---排序字段名
     * @param sortOrder     ---排序规则(ASC/DESC)
     * @return
     */
    @Override
    public DhPageInfo<ClueVO> selectPrivatePoolClueList(ClueQO clueQO,ClueSeniorQO clueSeniorQO,Integer pageIndex, Integer pageSize, String sortName, String sortOrder) {
        if (pageIndex != null && pageSize != null) {
            PageHelper.startPage(pageIndex, pageSize);
        }

        //增加删除状态查询条件(0:正常;1:已删除)
        clueQO.setDeleteStatus((short) StatusCodeEnum.NORMAL_CODE.getState());

        //排序
        StringBuilder order = new StringBuilder();
        if(!StringUtils.isBlank(sortName)&&!StringUtils.isBlank(sortOrder)){
            switch(sortName){
                case "inPoolTime":
                {
                    order.append("inPoolTime ").append(sortOrder);//创建时间
                }
                break;
                case "source":
                {
                    order.append("source ").append(sortOrder);//创建时间
                }
                break;
                default:
                    break;
            }
        }
        List<ClueVO> clueVOList = clueDbService.selectPrivatePoolClueList(clueQO,clueSeniorQO,order.toString());
        if(clueQO.getDefaultMark() != 0 && clueVOList != null && clueVOList.size() > 0){//非个人默认池
            for(ClueVO clueVO:clueVOList){
                long collectionTimes = clueReceiveDbService.selectReceiveCountByClueId(clueVO.getClueId());//领取次数
                clueVO.setCollectionTimes(collectionTimes);
                long returnTimes = clueReturnDbService.selectReturnCountByClueId(clueVO.getClueId());//退回次数
                clueVO.setReturnTimes(returnTimes);
                //设置线索来源中文
                Dictionary dictionary = dictionaryService.selectDictionaryByOne(DictionaryEnum.CLUE_SOURCE.getTypeCode(), clueVO.getSource());
                if(dictionary!=null){
                    clueVO.setSource(dictionary.getDictName());
                }
            }
        }
        PageInfo<ClueVO> pageInfo = new PageInfo<ClueVO>(clueVOList);
        return new DhPageInfo<ClueVO>(pageInfo, clueVOList);
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    public int addClue(ClueAddQO clueAddQO) {
        //1、查询线索池容量
        //获取线索池id
        String cluePoolId = clueAddQO.getCluePoolPublicId();
        //公司名称
        String companyName = clueAddQO.getCompanyName();
        //统一社会信用代码
        String unifiedSocialCreditCode = clueAddQO.getUnifiedSocialCreditCode();
        //调用企查查企业工商核验接口
        if(clueAddQO.getMenuIdentify() !=null && 1 == clueAddQO.getMenuIdentify()){
            String responseCode = getVerification(companyName,unifiedSocialCreditCode);
            if(!"200".equals(responseCode)){
                System.out.println("查询工商核验信息失败··········");
                return 3;
            }
        }

        //线索类型：1-公有；2-私有
        if(clueAddQO.getClueType()==1){
            //添加公有池
            //获取线索池容量
            CluePoolPublic cluePoolPublic = cluePoolPublicDbService.selectCluePoolPublicById(cluePoolId);
            int capacity = cluePoolPublic.getCapacity();
            //查询已经存在的线索数
            long num = clueDbService.selectCluePublicCount(cluePoolId);
            if(num<capacity){

                //2、查询线索是否重复（联系人电话和统一社会信用代码同时唯一）
                Boolean ClueIfRepeated = clueDbService.selectClueIfRepeated(companyName,unifiedSocialCreditCode);
                if(!ClueIfRepeated){
                    Clue clue = addClueModel(clueAddQO);
                    clueDbService.insertClue(clue);
                    return 0;
                }else {
                    //线索已重复
                    return 2;
                }
            }else {
                //已经超线索数量
                return 1;
            }
        }else {
            //添加私有池
            //2、查询线索是否重复（公司名称和统一社会信用代码同时唯一）
            Boolean ClueIfRepeated = clueDbService.selectClueIfRepeated(companyName,unifiedSocialCreditCode);
            if(!ClueIfRepeated){
                Clue clue = addClueModel(clueAddQO);
                clueDbService.insertClue(clue);
                return 0;
            }else {
                //线索已重复
                return 2;
            }
        }

    }

    //拼凑线索model
    public Clue addClueModel(ClueAddQO clueAddQO){
        UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();
        Clue clue = new Clue();
        clue.setClueId(CommonUtils.getGUID());
        String number = clueRedisService.getClueNumberByProvinceId(clueAddQO.getProvinceId());
        String clueNumber = ClueNumberEnum.getValue(clueAddQO.getProvinceId()) + number;
        clue.setClueNumber(clueNumber);
        clue.setContactPerson(clueAddQO.getContactPerson());
        clue.setContactPersonPhone(clueAddQO.getContactPersonPhone());
        clue.setSex(clueAddQO.getSex());
        clue.setCompanyName(clueAddQO.getCompanyName());
        clue.setJob(clueAddQO.getJob());
        clue.setRating(clueAddQO.getRating());
        clue.setSource(clueAddQO.getSource());
        clue.setClientCategories(clueAddQO.getClientCategories());
        clue.setClientLevel(clueAddQO.getClientLevel());
        clue.setUnifiedSocialCreditCode(clueAddQO.getUnifiedSocialCreditCode());
        clue.setIndustry(clueAddQO.getIndustry());
        clue.setCompanySize(clueAddQO.getCompanySize());
        clue.setCompanyWebsite(clueAddQO.getCompanyWebsite());
        clue.setRegisteredCapital(clueAddQO.getRegisteredCapital());
        clue.setOrganizationCode(clueAddQO.getOrganizationCode());
        clue.setCompanyType(clueAddQO.getCompanyType());
        clue.setLegalRepresentative(clueAddQO.getLegalRepresentative());
        clue.setEnterpriseExternalPhone(clueAddQO.getEnterpriseExternalPhone());
        clue.setEnterpriseExternalLandline(clueAddQO.getEnterpriseExternalLandline());
        clue.setBusinessScope(clueAddQO.getBusinessScope());
        clue.setRegistrationTime(clueAddQO.getRegistrationTime());
        clue.setCapitalType(clueAddQO.getCapitalType());
        clue.setRegistrationNumber(clueAddQO.getRegistrationNumber());
        clue.setEnterpriseState(clueAddQO.getEnterpriseState());
        clue.setInsuredNumber(clueAddQO.getInsuredNumber());
        clue.setCompanyEmail(clueAddQO.getCompanyEmail());
        clue.setWechat(clueAddQO.getWechat());
        clue.setRemark(clueAddQO.getRemark());
        clue.setConversionTime(clueAddQO.getConversionTime());
        clue.setClueState(clueAddQO.getClueState());
        clue.setDeleteStatus(Short.parseShort(String.valueOf(StatusCodeEnum.NORMAL_CODE.getState())));
        clue.setCreatePeopleId(userAccount.getAccountId());
        clue.setCreateTm(new Date());
        clue.setUpdatePeopleId(userAccount.getAccountId());
        clue.setUpdateTm(new Date());
        clue.setClueType(clueAddQO.getClueType());
        clue.setBusinessRegistrationNumber(clueAddQO.getBusinessRegistrationNumber());
        clue.setPaidInCapital(clueAddQO.getPaidInCapital());
        clue.setTaxpayerIdentificationNumber(clueAddQO.getTaxpayerIdentificationNumber());
        clue.setRegistrationAuthority(clueAddQO.getRegistrationAuthority());
        clue.setApprovedDate(clueAddQO.getApprovedDate());
        clue.setEstablishmentDate(clueAddQO.getEstablishmentDate());
        clue.setImportAndExportEnterpriseCode(clueAddQO.getImportAndExportEnterpriseCode());
        clue.setCompanyAddress(clueAddQO.getCompanyAddress());
        clue.setProvinceId(clueAddQO.getProvinceId());
        clue.setProvinceName(clueAddQO.getProvinceName());
        clue.setCityId(clueAddQO.getCityId());
        clue.setCityName(clueAddQO.getCityName());
        clue.setTag(clueAddQO.getTag());
        if(clueAddQO.getClueType()==1){
            clue.setCluePoolPublicId(clueAddQO.getCluePoolPublicId());
        }else {
            clue.setCluePoolPrivateId(clueAddQO.getCluePoolPrivateId());
        }
        return clue;
    }

    /**
     * 线索--分配
     * @param distributeUserId  ---分配人员ID
     * @param clueId            ---线索主键
     * @param poolId            ---原线索池ID
     * @return
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    public Map<String,Object> updateClueDistribute(String distributeUserId,String clueId,String poolId) {
        Map<String,Object> result = new HashMap<String,Object>();
        try{
            UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();//获取登录人信息
            String accountId = userAccount.getAccountId();
            String clue_pool_private_id = cluePoolPrivateDbService.selectCluePoolPrivateId(distributeUserId,(short)StatusCodeEnum.NORMAL_CODE.getState());
            if(!StringUtils.isBlank(clue_pool_private_id) && !StringUtils.isBlank(distributeUserId)){
                //1.根据个人线索池Id查询所分配的线索条数
                long count = clueDbService.selectCluePrivateCount(clue_pool_private_id);
                if(count < 300){
                    //2.修改线索表(cp_clue)
                    Clue clue = new Clue();
                    clue.setClueId(clueId);//线索主键
                    clue.setUpdatePeopleId(accountId);//更新人ID
                    clue.setUpdateTm(new Date());//更新时间
                    clue.setClueState(ServiceCodeEnum.CLUE_STATE_ASSIGNED.getCode());//分配状态修改为已分配
                    clue.setCluePoolPrivateId(clue_pool_private_id);//个人默认池主键
                    clue.setOwnerId(distributeUserId);//当前拥有人ID
                    clue.setOwnerStartTm(new Date());//拥有人起始时间
                    int updateResult = clueDbService.updateClueDistribute(clue);
                    if(updateResult > 0){
                        // 3.新增线索领取/分配记录(cp_clue_receive)
                        clueReceiveDbService.insertClueReceive(poolId,clue_pool_private_id,clueId,distributeUserId,2);
                        result.put("d000","分配成功");
                    }
                }else{
                    result.put("d001","已分配的线索数达到最大值,不能进行分配");
                }
            }else{
                result.put("d002","没有个人默认池不能分配");
            }
        }catch(RuntimeException e){
            throw e;
        }
        return result;
    }

    /**
     * 线索--收回
     * @return
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    public void retrieveClue(ClueQO clueQO){
        UserAccount userAccount = (UserAccount)SecurityUtils.getSubject().getPrincipal();//获取登录人信息
        try{
            //1.修改线索表(cp_clue)
            clueQO.setUpdateTm(new Date());//更新时间
            clueQO.setUpdatePeopleId(userAccount.getAccountId());//更新人ID
            clueQO.setClueState(ServiceCodeEnum.CLUE_STATE_INPOOL.getCode());//线索状态(0-在池；1-已领取；2-已分配;3:已转化)
            int updateClueStateResult = clueDbService.updateClueState(clueQO);
            if(updateClueStateResult > 0){
                //2.新增线索退回记录表(cp_clue_return)
                clueReturnService.insertClueReturn(userAccount.getAccountId(),clueQO.getClueId(),"1",clueQO.getReturnReason(),clueQO.getCluePoolFromId(),clueQO.getCluePoolToId());
            }
        }catch(RuntimeException e){
            throw e;
        }
    }

    /**
     * 线索删除
     * @param clueQO  ---线索
     * @return
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public Boolean deleteClueById(ClueQO clueQO) {
        UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();//获取登录人信息
        clueQO.setUpdateTm(new Date());//更新时间
        clueQO.setUpdatePeopleId(userAccount.getAccountId());//更新人ID
        clueQO.setDeleteStatus((short)StatusCodeEnum.DELETE_CODE.getState());//删除
        return clueDbService.updateDeleteStatusById(clueQO) > 0;
    }

    /**
     * 管理系统--根据线索ID批量删除线索(将delete_status置为1)
     * @param clueIds
     * @return
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public Boolean batchDeleteClueByClueIds(List clueIds) {
        UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();//获取登录人信息
        ClueQO clueQO = new ClueQO();
        clueQO.setUpdatePeopleId(userAccount.getAccountId());//更新人ID
        clueQO.setUpdateTm(new Date());//更新时间
        clueQO.setDeleteStatus((short)StatusCodeEnum.DELETE_CODE.getState());
        return clueDbService.batchDeleteClueByClueIds(clueIds,clueQO);
    }

    /**
     * 线索池删除时根据线索池ID查询该线索池里线索的已分配和已领取总数
     * @param cluePoolPublicId ---线索池ID
     * @return
     */
    @Override
    public long selectDistributedOrReceiveCount(String cluePoolPublicId) {
        return clueDbService.selectDistributedOrReceiveCount(cluePoolPublicId);
    }

    /**
     * 根据线索池ID查询公司
     * @param cluePollId  ---线索池ID
     * @return
     */
    @Override
    public   List<UserCompanyVO>  selectDistributeCompany(String cluePollId) {
        return clueDbService.selectDistributeCompany(cluePollId);
    }

    /**
     * 根据用户名查询用户信息及所在公司信息(全国公有池、分公司公有池-分配-按人员姓名模糊查找)
     * @param userName ---用户名
     * @return
     */
    @Override
    public List<UserCompanyVO> selectUserAndCompany(String userName) {
        return clueDbService.selectUserAndCompany(userName);
    }

    /**
     * 查询分公司公有池的用户
     * @param companyIds ---公司ID集合
     * @return
     */
    @Override
    public  List<UserCompanyVO> selectUserByPoolPermission(List<String> companyIds,String userName) {
        return clueDbService.selectUserByPoolPermission(companyIds,userName);
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public int editClue(Clue clue) {
        UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();
        String clueId = clue.getClueId();
        Clue clueOld = clueDbService.selectClueByClueId(clueId);
        clue.setClueNumber(clueOld.getClueNumber());
        clue.setClueState(clueOld.getClueState());
        clue.setDeleteStatus(Short.parseShort(String.valueOf(StatusCodeEnum.NORMAL_CODE.getState())));
        clue.setCreatePeopleId(clueOld.getCreatePeopleId());
        clue.setCreateTm(clueOld.getCreateTm());
        clue.setUpdatePeopleId(userAccount.getAccountId());
        clue.setUpdateTm(new Date());
        clue.setClueType(clueOld.getClueType());
        clue.setOwnerId(clueOld.getOwnerId());
        clue.setOwnerStartTm(clueOld.getOwnerStartTm());
        clue.setConversionTime(clueOld.getConversionTime());
        //查询线索是否重复（公司名称和统一社会信用代码同时唯一）
        //联系人电话
        String companyName = clue.getCompanyName();
        //统一社会信用代码
        String unifiedSocialCreditCode = clue.getUnifiedSocialCreditCode();
        Boolean isClueRepeated = clueDbService.selectIsClueRepeated(companyName, unifiedSocialCreditCode, clueId);
        if(!isClueRepeated){
            clueDbService.updateClue(clue);
            return 0;
        }else {
            //线索已重复
            return 2;
        }
    }

    @Override
    public ClueEditVO selectClueByClueId(String clueId) {
        Clue clue = clueDbService.selectClueByClueId(clueId);
        ClueEditVO clueEditVO = new ClueEditVO();
        BeanUtils.copyProperties(clue,clueEditVO);
        clueEditVO.setPaidInCapital(clue.getPaidInCapital().intValue());
        clueEditVO.setRegisteredCapital(clue.getRegisteredCapital().intValue());

        //性别
        String sex = clueEditVO.getSex();
        if(sex != null){
            if("0".equals(sex)){
                clueEditVO.setSexValue("男");
            } else if("1".equals(sex)){
                clueEditVO.setSexValue("女");
            }
        }
        //线索评级
        Integer rating = clueEditVO.getRating();
        if(rating != null){
            Dictionary dictionary =  dictionaryDbService.selectDictionaryByOne(DictionaryEnum.CLUE_RATING.getTypeCode(),String.valueOf(rating));
            clueEditVO.setRatingValue(dictionary.getDictName());
        }
        //客户类别
        String clientCategories = clueEditVO.getClientCategories();
        if(!StringUtils.isBlank(clientCategories)){
            Dictionary dictionary =  dictionaryDbService.selectDictionaryByOne(DictionaryEnum.CLIENT_CATEGORIES.getTypeCode(),clientCategories);
            clueEditVO.setClientCategoriesValue(dictionary.getDictName());
        }
        //客户级别
        String clientLevel = clueEditVO.getClientLevel();
        if(!StringUtils.isBlank(clientLevel)){
            Dictionary dictionary =  dictionaryDbService.selectDictionaryByOne(DictionaryEnum.CLIENT_LEVEL.getTypeCode(),clientLevel);
            clueEditVO.setClientLevelValue(dictionary.getDictName());
        }
        //公司规模
        String companySize = clueEditVO.getCompanySize();
        if(!StringUtils.isBlank(companySize)){
            Dictionary dictionary =  dictionaryDbService.selectDictionaryByOne(DictionaryEnum.COMPANY_SIZE.getTypeCode(),companySize);
            clueEditVO.setCompanySizeValue(dictionary.getDictName());
        }
        //公司类型
        String companyType = clueEditVO.getCompanyType();
        if(!StringUtils.isBlank(companyType)){
            Dictionary dictionary =  dictionaryDbService.selectDictionaryByOne(DictionaryEnum.COMPANY_TYPE.getTypeCode(),companyType);
            clueEditVO.setCompanyTypeValue(dictionary.getDictName());
        }
        //资本类型
        String capitalType = clueEditVO.getCapitalType();
        if(!StringUtils.isBlank(capitalType)){
            Dictionary dictionary =  dictionaryDbService.selectDictionaryByOne(DictionaryEnum.CAPITAL_TYPE.getTypeCode(),capitalType);
            clueEditVO.setCapitalTypeValue(dictionary.getDictName());
        }
        //企业状态
        String enterpriseState = clueEditVO.getEnterpriseState();
        if(!StringUtils.isBlank(enterpriseState)){
            Dictionary dictionary =  dictionaryDbService.selectDictionaryByOne(DictionaryEnum.ENTERPRISE_STATE.getTypeCode(),enterpriseState);
            clueEditVO.setEnterpriseStateValue(dictionary.getDictName());
        }
        //线索来源
        String source = clueEditVO.getSource();
        if(!StringUtils.isBlank(source)){
            Dictionary dictionary =  dictionaryDbService.selectDictionaryByOne(DictionaryEnum.CLUE_SOURCE.getTypeCode(),source);
            if(dictionary!=null){
                clueEditVO.setSourceValue(dictionary.getDictName());
            }
        }
        //行业
        String industry = clueEditVO.getIndustry();
        if(!StringUtils.isBlank(industry)){
            Dictionary dictionary =  dictionaryDbService.selectDictionaryByOne(DictionaryEnum.INDUSTRY.getTypeCode(),industry);
            if(dictionary!=null){
                clueEditVO.setIndustryValue(dictionary.getDictName());
            }
        }
        //注册时间
        Date registrationTime = clueEditVO.getRegistrationTime();
        if(registrationTime != null){
            clueEditVO.setRegistrationTimeFormat(DateUtil.formatDate(registrationTime));
        }
        //核准日期
        Date approvedDate = clueEditVO.getApprovedDate();
        if(approvedDate != null){
            clueEditVO.setApprovedDateFormat(DateUtil.formatDate(approvedDate));
        }
        //成立日期
        Date establishmentDate = clueEditVO.getEstablishmentDate();
        if(establishmentDate != null){
            clueEditVO.setEstablishmentDateFormat(DateUtil.formatDate(establishmentDate));
        }

        return clueEditVO;
    }



    /**
     * @author wll
     * info 线索池公海-线索清单
     */
    @Override
    public DhPageInfo<ClueVO> selectClueInfo(ClueQO clueQO, Integer pageIndex, Integer pageSize, String sortName, String sortOrder) {
        if (pageIndex != null && pageSize != null) {
            PageHelper.startPage(pageIndex, pageSize);
        }
        //排序
        StringBuilder order = new StringBuilder();
        if(!StringUtils.isBlank(sortName)&&!StringUtils.isBlank(sortOrder)){
            switch(sortName){

                case "source":
                {
                    order.append("source ").append(sortOrder);//线索来源
                }
                break;
                default:
                    break;
            }
        }
        List<ClueVO> clueVOList = clueDbService.selectClueInfo(clueQO,order.toString(),DictionaryEnum.CLUE_SOURCE.getTypeCode());
        if(clueQO != null && clueQO.getSpecializedIndustry() != null && clueQO.getSpecializedIndustry().trim().length() > 0){
            if(clueVOList != null && clueVOList.size() > 0){
                for(ClueVO clueVO : clueVOList){
                    clueVO.setSearchType(true);
                }
            }
        }
        PageInfo<ClueVO> pageInfo = new PageInfo<ClueVO>(clueVOList);
        return new DhPageInfo<ClueVO>(pageInfo, clueVOList);
    }

    /**
     *info 用户模块-我的线索池-线索清单
     * @return
     */
    @Override
    public DhPageInfo<ClueVO> getMyClueList(ClueQO clueQO, ClueExtentQO clueExtentQO, Integer pageIndex, Integer pageSize, String sortName, String sortOrder) {
        if (pageIndex != null && pageSize != null) {
            PageHelper.startPage(pageIndex, pageSize);
        }
        //排序
        StringBuilder order = new StringBuilder();
        if(!StringUtils.isBlank(sortName)&&!StringUtils.isBlank(sortOrder)){
            switch(sortName){
                case "ownerStartTm":
                {
                    order.append("owner_start_tm ").append(sortOrder);//线索来源
                }
                break;
                case "source":
                {
                    order.append("source ").append(sortOrder);//线索来源
                }
                break;
                default:
                    break;
            }
        }

        // 处理区间参数
        // 成立年限
        if (StringUtils.isNotBlank(clueExtentQO.getApprovalDate())) {
            if (null != clueExtentQO.getIsAutoApprovalDate() && clueExtentQO.getIsAutoApprovalDate().booleanValue()) { // 自定义格式 YYYY-MM-DD至YYYY-MM-DD
                String[] autoApprovalDate = clueExtentQO.getApprovalDate().split("至");
                if (autoApprovalDate.length == 2) {
                    // 比较两个日期的大小
                    if (autoApprovalDate[0].trim().compareTo(autoApprovalDate[1].trim()) > 0) {
                        clueExtentQO.setStartApprovalDate(autoApprovalDate[1].trim());
                        clueExtentQO.setEndApprovalDate(autoApprovalDate[0].trim());
                    } else {
                        clueExtentQO.setStartApprovalDate(autoApprovalDate[0].trim());
                        clueExtentQO.setEndApprovalDate(autoApprovalDate[1].trim());
                    }
                }
            } else {
                String approval = clueExtentQO.getApprovalDate().substring(0, clueExtentQO.getApprovalDate().indexOf("年")).trim(); // 年限
                if (clueExtentQO.getApprovalDate().contains("上")) {
                    Calendar approvalDate = Calendar.getInstance();
                    approvalDate.add(Calendar.YEAR, -Integer.valueOf(approval));
                    String approvalDateFormat = cn.hutool.core.date.DateUtil.format(approvalDate.getTime(), "yyyy-MM-dd");
                    clueExtentQO.setEndApprovalDate(approvalDateFormat);
                } else if (clueExtentQO.getApprovalDate().contains("内")) {
                    if ("半".equals(approval)) { // 半年内
                        Calendar approvalDate = Calendar.getInstance();
                        approvalDate.add(Calendar.MONTH, -6);
                        String approvalDateFormat = cn.hutool.core.date.DateUtil.format(approvalDate.getTime(), "yyyy-MM-dd");
                        clueExtentQO.setStartApprovalDate(approvalDateFormat);
                    } else { // xx年内
                        Calendar approvalDate = Calendar.getInstance();
                        approvalDate.add(Calendar.YEAR, -Integer.valueOf(approval));
                        String approvalDateFormat = cn.hutool.core.date.DateUtil.format(approvalDate.getTime(), "yyyy-MM-dd");
                        clueExtentQO.setStartApprovalDate(approvalDateFormat);
                    }
                } else if (clueExtentQO.getApprovalDate().contains("-")) { // 非自定义日期的年限区间
                    if (approval.startsWith("-")) {
                        String approvalS = approval.substring(1);
                        if (StringUtils.isNotBlank(approvalS)) {
                            Calendar approvalDate = Calendar.getInstance();
                            approvalDate.add(Calendar.MONTH, -Integer.valueOf(approvalS));
                            String approvalDateFormat = cn.hutool.core.date.DateUtil.format(approvalDate.getTime(), "yyyy-MM-dd");
                            clueExtentQO.setStartApprovalDate(approvalDateFormat);
                        }
                    } else if (approval.endsWith("-")) {
                        String approvalE = approval.substring(0, approval.indexOf("-"));
                        if (StringUtils.isNotBlank(approvalE)) {
                            Calendar approvalDate = Calendar.getInstance();
                            approvalDate.add(Calendar.YEAR, -Integer.valueOf(approvalE));
                            String approvalDateFormat = cn.hutool.core.date.DateUtil.format(approvalDate.getTime(), "yyyy-MM-dd");
                            clueExtentQO.setEndApprovalDate(approvalDateFormat);
                        }
                    } else {
                        String[] approvalArr = approval.split("\\-+");
                        Calendar approvalDate1 = Calendar.getInstance();
                        approvalDate1.add(Calendar.YEAR, -Integer.valueOf(approvalArr[0]));
                        String approvalDateFormat1 = cn.hutool.core.date.DateUtil.format(approvalDate1.getTime(), "yyyy-MM-dd");

                        Calendar approvalDate2 = Calendar.getInstance();
                        approvalDate2.add(Calendar.YEAR, -Integer.valueOf(approvalArr[1]));
                        String approvalDateFormat2 = cn.hutool.core.date.DateUtil.format(approvalDate2.getTime(), "yyyy-MM-dd");
                        if (approvalDate1.compareTo(approvalDate2) > 0) { // 保证查询的区间正确
                            clueExtentQO.setStartApprovalDate(approvalDateFormat2.trim());
                            clueExtentQO.setEndApprovalDate(approvalDateFormat1.trim());
                        } else {
                            clueExtentQO.setStartApprovalDate(approvalDateFormat1.trim());
                            clueExtentQO.setEndApprovalDate(approvalDateFormat2.trim());
                        }
                    }
                }
            }
        }

        // 注册资本
        if (StringUtils.isNotBlank(clueExtentQO.getRegistCapital())) {
            String registCapital = clueExtentQO.getRegistCapital().substring(0, clueExtentQO.getRegistCapital().indexOf("万"));
            if (clueExtentQO.getRegistCapital().contains("上")) { // xx以上 或 xx-
                clueExtentQO.setStartRegistCapital(new BigDecimal(registCapital));
            } else if (clueExtentQO.getRegistCapital().contains("内")){ // xx以内 或 -xx
                clueExtentQO.setEndRegistCapital(new BigDecimal(registCapital));
            } else if (registCapital.contains("-")){
                if (registCapital.startsWith("-")) {
                    String registCapitalS = registCapital.substring(1);
                    if (StringUtils.isNotBlank(registCapitalS)) {
                        clueExtentQO.setEndRegistCapital(new BigDecimal(registCapitalS));
                    }
                } else  if (registCapital.endsWith("-")) {
                    String registCapitalE = registCapital.substring(0, registCapital.indexOf("-")).trim();
                    if (StringUtils.isNotBlank(registCapitalE)) {
                        clueExtentQO.setStartRegistCapital(new BigDecimal(registCapitalE));
                    }
                } else {
                    String[] sourceArr = registCapital.split("\\-+"); // 正则分割字符串，只取前两个
                    if (Integer.valueOf(sourceArr[0]) > Integer.valueOf(sourceArr[1])) { // 保证范围查询的准确性
                        clueExtentQO.setStartRegistCapital(new BigDecimal(sourceArr[1]));
                        clueExtentQO.setEndRegistCapital(new BigDecimal(sourceArr[0]));
                    } else {
                        clueExtentQO.setStartRegistCapital(new BigDecimal(sourceArr[0]));
                        clueExtentQO.setEndRegistCapital(new BigDecimal(sourceArr[1]));
                    }
                }
            } else {
                clueExtentQO.setStartRegistCapital(new BigDecimal(registCapital));
            }
        }

        // 参保人数
        if (StringUtils.isNotBlank(clueExtentQO.getInsuredTotal())) {
            String insuredTotal = clueExtentQO.getInsuredTotal().substring(0, clueExtentQO.getInsuredTotal().indexOf("人"));
            if (clueExtentQO.getInsuredTotal().contains("上")) { // xx以上 或 xx-
                clueExtentQO.setStartInsuredTotal(Integer.valueOf(insuredTotal));
            } else if (clueExtentQO.getInsuredTotal().contains("内")){ // xx以内 或 -xx
                clueExtentQO.setEndInsuredTotal(Integer.valueOf(insuredTotal));
            } else if (insuredTotal.contains("-")){
                if (insuredTotal.startsWith("-")) {
                    String insuredTotalS = insuredTotal.substring(1);
                    if (StringUtils.isNotBlank(insuredTotalS)) {
                        clueExtentQO.setEndInsuredTotal(Integer.valueOf(insuredTotalS));
                    }
                } else  if (insuredTotal.endsWith("-")) {
                    String insuredTotalE = insuredTotal.substring(0, insuredTotal.indexOf("-")).trim();
                    if (StringUtils.isNotBlank(insuredTotalE)) {
                        clueExtentQO.setStartInsuredTotal(Integer.valueOf(insuredTotalE));
                    }
                } else {
                    String[] sourceArr = insuredTotal.split("\\-+"); // 正则分割字符串，只取前两个
                    if (Integer.valueOf(sourceArr[0]) > Integer.valueOf(sourceArr[1])) { // 保证范围查询的准确性
                        clueExtentQO.setStartInsuredTotal(Integer.valueOf(sourceArr[1]));
                        clueExtentQO.setEndInsuredTotal(Integer.valueOf(sourceArr[0]));
                    } else {
                        clueExtentQO.setStartInsuredTotal(Integer.valueOf(sourceArr[0]));
                        clueExtentQO.setEndInsuredTotal(Integer.valueOf(sourceArr[1]));
                    }
                }
            } else {
                clueExtentQO.setStartInsuredTotal(Integer.valueOf(insuredTotal));
            }
        }

        List<ClueVO> clueVOList = clueDbService.getMyClueList(clueQO, clueExtentQO, order.toString(),DictionaryEnum.CLUE_SOURCE.getTypeCode());
        PageInfo<ClueVO> pageInfo = new PageInfo<ClueVO>(clueVOList);
        return new DhPageInfo<ClueVO>(pageInfo, clueVOList);
    }

    /**
     * @author wll
     * info 我的线索池-线索清单释放
     * @param clueQO
     * @return
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    public void releaseClue(ClueQO clueQO) {
        UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();//获取登录人信息
        //查询全国默认池的信息
        CluePoolPublic cluePoolPublic = cluePoolPublicDbService.selectNationalDefaultPoolInfo();
        Map map = new HashMap();
        map.put("clueState",0); //线索状态：0-在池；1-已领取；2-已分配
        map.put("cluePoolPublicId",cluePoolPublic.getCluePoolPublicId());//全国默认池id
        map.put("clueId",clueQO.getClueId());//当前线索id
        map.put("updateTm",new Date());//更新时间
        map.put("updatePeopleId",userAccount.getAccountId());//更新人
        map.put("defaultMark",clueQO.getDefaultMark());//是否是默认池(0:不是默认;1:默认池子)
        try{
        Boolean result = clueDbService.modifyClueData(map);
        if(result){
            //2.新增线索退回记录表(cp_clue_return)
            clueQO.setCluePoolToId(cluePoolPublic.getCluePoolPublicId());//线索池id: 释放到哪个池子的池子id
            Boolean status = clueReturnService.insertClueReturn(userAccount.getAccountId(),clueQO.getClueId(),"2",clueQO.getReturnReason(),clueQO.getCluePoolFromId(),cluePoolPublic.getCluePoolPublicId());
        }
        }catch(RuntimeException e){
            throw e;
        }
    }

    @Override
    public long selectCluePoolPrivateCount(String cluePoolPrivateId) {
        return clueDbService.selectCluePoolPrivateCount(cluePoolPrivateId);
    }

    @Override
    public long selectClueCountByPublicPoolId(String cluePoolPublicId) {
        return clueDbService.selectCluePublicCount(cluePoolPublicId);
    }

    @Override
    public long clueZeroTimeReceiveCount(String cluePoolId) {
        return clueDbService.clueZeroTimeReceiveCount(cluePoolId);
    }

    /**
     * 线索总转化数
     * @param cluePoolPublicId  线索池公有id
     * @return
     */
    @Override
    public long selectClueConverCountByPublicPoolId(String cluePoolPublicId) {
        return clueDbService.selectClueConverCountByPublicPoolId(cluePoolPublicId);
    }


    /**
     * @author wll
     * info 线索池公海-线索表单-领取
     * @param clueQO 线索信息
     * @param poolId 线索池id
     * @return
     */
    @Override
    public JSONObject receiveClue(ClueQO clueQO,String poolId) {
        UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();//当前登陆人信息
        JSONObject result = new JSONObject();
        //一:当前线索状态是否在池(公海里的线索同一时间可以很多人操作同一条线索) 删除状态是否正常
        result = clueDbService.checkClueIsInThePool(clueQO);
        if(!result.getBoolean("status")){
            return result;
        }

        //查询个人默认池信息
        CluePoolPrivate cluePoolPrivate = cluePoolPrivateDbService.selectCluePoolPrivate(userAccount);
        //如果客户默认池不存在则创建默认池
        if(cluePoolPrivate==null){
            String clueId = CommonUtils.getGUID();
            CluePoolPrivate cluePoolPrivateMy = new CluePoolPrivate();
            cluePoolPrivateMy.setCluePoolPrivateId(clueId);
            cluePoolPrivateMy.setCluePoolName(userAccount.getUserName()+"的线索默认池");
            cluePoolPrivateMy.setCapacity(300);
            cluePoolPrivateMy.setDeleteStatus(Short.parseShort("0"));
            cluePoolPrivateMy.setCreatePeopleId(userAccount.getAccountId());
            cluePoolPrivateMy.setCreateTm(new Date());
            cluePoolPrivateMy.setDefaultMark(1);
            cluePoolPrivateMy.setCompanyId(userAccount.getCompanyId());
            SysCompany sysCompany = sysCompanyDbService.selectSysCompanyById(userAccount.getCompanyId());
            cluePoolPrivateMy.setCompanyName(sysCompany.getCompanyName());
            cluePoolPrivateDbService.insertCluePoolPrivateInfo(cluePoolPrivateMy);
            cluePoolPrivate = cluePoolPrivateDbService.selectCluePoolPrivateById(clueId);
        }


        //二:个人默认池容量 满了不能进行领取
        result = cluePoolPrivateDbService.selectCluePoolPrivateDefaultCapacity(cluePoolPrivate);
        if(!result.getBoolean("status")){
            return result;
        }

        //当前线索池规则信息 cp_clue_pool_rule
        CluePoolRule cluePoolRuleInfo = cluePoolRuleDbService.selectCluePoolMaxReceive(poolId);
        if(null != cluePoolRuleInfo){
            //三:线索领取量是否超过该池设置的最大领取量
            result = clueReceiveDbService.selectClueReceiveInfo(userAccount,poolId,cluePoolRuleInfo);
            if(!result.getBoolean("status")){
                return result;
            }

            //同一线索释放或者收回的最新一条记录信息
            ClueReturn clueReturn = clueReturnDbService.selectLatestClueReturnOneInfo(clueQO);
            //四:同一线索是否满足(释放 收回)时间间隔  小时
            result = clueReturnDbService.selectTheSameThatClueTimeInterval(cluePoolRuleInfo.getTimeInterval(),clueReturn);
            if(!result.getBoolean("status")){
                return result;
            }

            //五:同一线索池线索的领取时间间隔是否满足
            result = clueReceiveDbService.TimeIntervalFromLastClue(poolId,cluePoolRuleInfo.getContinueTimeInterval(),userAccount);
            if(!result.getBoolean("status")){
                return result;
            }
        }
        //六:线索领取到个人默认池 同时添加领取记录
        result = clueDbService.getClueToThePersonalDefaultPool(cluePoolPrivate,clueQO,poolId);
        return result;
    }


    @Override
    public Clue selectOneClue() {
        return clueDbService.selectOneClue();
    }

    @Override
    public long getCluePoolConversionStatisticsForOneMonth(String cluePoolId, String yearMonth) throws ParseException {
        long count = clueDbService.getCluePoolConversionStatisticsForOneMonth(cluePoolId, yearMonth);
        return count;
    }


    @Override
    public String getVerification(String customerName,String unifiedSocialCreditCode){
        String appkey = redisUtil.get("qcc_appkey");
        String seckey = redisUtil.get("qcc_keyword");
        String reqInterNme = "http://api.qichacha.com/ECIV4/SearchWide";
        String paramStr = "keyword="+unifiedSocialCreditCode;//社会信用代码
        QccSearchWideVO qccSearchWideVO = new QccSearchWideVO();
        String responseStatus = "";
        try {
            // auth header setting
            HttpHead reqHeader = new HttpHead();
            String[] autherHeader = RandomAuthentHeader(appkey,seckey);
            reqHeader.setHeader("Token", autherHeader[0]);
            reqHeader.setHeader("Timespan", autherHeader[1]);
            final String reqUri = reqInterNme.concat("?key=").concat(appkey).concat("&").concat(paramStr);
            String tokenJson = HttpHelper.httpGet(reqUri, reqHeader.getAllHeaders());
            // parse status from json
            String status = FormartJson(tokenJson, "Status");
            if (!HttpCodeRegex.isAbnornalRequest(status)) {
                qccSearchWideVO = PrettyPrintJson(tokenJson);
            }
            responseStatus = qccSearchWideVO.getStatus();//调用接口返回的状态
            //往核验记录表插入一条记录
            UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();//当前登陆人信息
            QccSearch qccSearch = new QccSearch();
            qccSearch.setId(CommonUtils.getGUID());
            qccSearch.setCustomerName(customerName);
            qccSearch.setCreateUserId(userAccount.getAccountId());
            qccSearch.setCompanyId(userAccount.getCompanyId());//当前用户所属公司
            qccSearch.setUnifiedSocialCreditCode(unifiedSocialCreditCode);
            if(("200".equals(responseStatus))){
                String qccName = qccSearchWideVO.getResult().get(0).getName();
                String qccCreditCode = qccSearchWideVO.getResult().get(0).getCreditCode();
                qccSearch.setQccName(qccName);
                qccSearch.setQccCreditCode(qccCreditCode);
                if(qccName.equals(customerName) && qccCreditCode.equals(unifiedSocialCreditCode)){
                    qccSearch.setSuccessFlag("Y");//调用接口成功并匹配成功
                }else{
                    qccSearch.setSuccessFlag("F");//查询的结果与输入的客户名称、信用代码匹配失败
                    responseStatus = "C00207";
                }
            }else{
                qccSearch.setSuccessFlag("N");//调用接口失败
            }
            qccSearchMapper.insertSelective(qccSearch);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return responseStatus;
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    public int updateUserClueTag(String tag, String clueId) throws RuntimeException {
        if (StringUtils.isBlank(clueId)) {
            throw new RuntimeException(ResponseCodeEnum.PARAMETER_ERROR.getResponseValue());
        }
        int result = this.clueDbService.updateUserClueTag(tag, clueId);
        if (result > 0) {
            Clue clue = clueRedisService.getClueById(clueId);
            if(clue!=null){
                clueRedisService.deleteClueById(clueId);
            }
        }
        return result;
    }

    // 获取返回码 Res Code
    static class HttpCodeRegex {
        private static final String ABNORMAL_REGIX = "(101)|(102)";
        private static final Pattern pattern = Pattern.compile(ABNORMAL_REGIX);
        protected static boolean isAbnornalRequest(final String status) {
            return pattern.matcher(status).matches();
        }
    }

    // 获取Auth Code
    private static final String[] RandomAuthentHeader(String appkey,String seckey) {
        String timeSpan = String.valueOf(System.currentTimeMillis() / 1000);
        String[] authentHeaders = new String[] { DigestUtils.md5Hex(appkey.concat(timeSpan).concat(seckey)).toUpperCase(), timeSpan };
        return authentHeaders;
    }

    // 解析JSON
    private static String FormartJson(String jsonString, String key) throws JSONException {
        org.json.JSONObject jObject = new org.json.JSONObject(jsonString);
        return (String) jObject.get(key);
    }

    // pretty print 返回值
    private static QccSearchWideVO PrettyPrintJson(String jsonString) throws JSONException {
        QccSearchWideVO qccSearchWideVO = new QccSearchWideVO();
        try {
            ObjectMapper mapper = new ObjectMapper();
            Object obj = mapper.readValue(jsonString, Object.class);
            String indented = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
            out.println(indented);
            qccSearchWideVO = new Gson().fromJson(indented, QccSearchWideVO.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return qccSearchWideVO;
    }


}
